package org.hadoop.service;

import org.hadoop.dao.HBseDao;
import org.hadoop.entity.TitleHot;
import org.hadoop.vo.TitleCount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class TitleHotService {
    @Autowired
    private HBseDao hBseDao;

    /**
     * 通过时间段查询数据
     */
    public List<TitleHot> findByTimeStamp(long start, long end) throws Exception {
        return hBseDao.query(start, end);
    }

    /**
     * 采用数据的形式  分组计数 select title,count(*) from title_hot group by count
     * 采用HashMap<String,Integer>(),key是标题(title)，value(count)是计数
     *
     * @param start
     * @param end
     * @return
     * @throws Exception
     */
    public List<TitleCount> findTitleCountByTimeStamp(long start, long end) throws Exception {
        //查询出原始数据
        List<TitleHot> list = hBseDao.query(start, end);
        Map<String, Integer> map = new HashMap<>();//标题，热度
        //map中key是唯一的，value不唯一
        for (TitleHot titleHot : list) {
            //  boolean containsKey(Object key); 判断key是否存在，若存在返回true，不存在返回false
            if (map.containsKey(titleHot.getTitle())) {
                //判断map中的key（标题）是否存在，若存在，把上一次的值+1；
                // V get(Object key); 根据键去取值
                map.put(titleHot.getTitle(), map.get(titleHot.getTitle()) + 1);
            } else {
                //若不存在，将该值设置为1
                map.put(titleHot.getTitle(), 1);
            }
        }
        //建议不直接用map作为返回，因为需要再取一次
        List<TitleCount> res = new ArrayList<>();
        for (String key : map.keySet()) {//Set<K> keySet();  获取所有键的集合
            TitleCount title_hot = new TitleCount();
            //将key设置到对象的title属性中
            title_hot.setTitle(key);
            //将value设置到对象的count属性中
            title_hot.setCount(map.get(key));
            res.add(title_hot);
        }
       /* res.sort(new Comparator<TitleCount>() {
            @Override
            public int compare(TitleCount o1, TitleCount o2) {
                return o1.getCount() - o2.getCount();
            }
        });*/

        //排序 取前10个数据
        //h1 h2 就是集合里边的对象，利用h1和h2作差，正则表示前一个大，负则表示后一个大
        res=res.stream().sorted((h1,h2)->
                -(h1.getCount()-h2.getCount())
                ).limit(10).collect(Collectors.toList());
        return res;
    }

    /**
     * 区分终端 可选时间段的热点分布
     * @param agent
     * @param start
     * @param end
     * @return
     */
    public List<TitleHot> countByAgentTimeStamp(String agent, long start, long end) throws Exception {
        //查询出原始数据
        List<TitleHot> list = hBseDao.query(start, end);
        //处理agent的值 ，如果没有表示不区分
        List<TitleHot> list1=list.stream()
                .filter(hot -> hot.getAgentType().equals(agent) || "".equals(agent))//只要和前端选择的相匹配的终端类型，和全部的情况
                .collect(Collectors.toList());
        Map<String, Integer> map = new HashMap<>();//标题，热度
        //map中key是唯一的，value不唯一
        for (TitleHot titleHot : list1) {
            //  boolean containsKey(Object key); 判断key是否存在，若存在返回true，不存在返回false
            if (map.containsKey(titleHot.getTitle())) {
                //判断map中的key（标题）是否存在，若存在，把上一次的值+1；
                // V get(Object key); 根据键去取值
                map.put(titleHot.getTitle(), map.get(titleHot.getTitle()) + 1);
            } else {
                //若不存在，将该值设置为1
                map.put(titleHot.getTitle(), 1);
            }
        }
        //建议不直接用map作为返回，因为需要再取一次
        List<TitleHot> res = new ArrayList<>();
        for (String key : map.keySet()) {//Set<K> keySet();  获取所有键的集合
            TitleHot title_hot = new TitleHot();
            //将key设置到对象的title属性中
            title_hot.setTitle(key);
            //将value设置到对象的count属性中
            title_hot.setCount(map.get(key));
            res.add(title_hot);
        }
       /* res.sort(new Comparator<TitleCount>() {
            @Override
            public int compare(TitleCount o1, TitleCount o2) {
                return o1.getCount() - o2.getCount();
            }
        });*/

        //排序 取前10个数据
        //h1 h2 就是集合里边的对象，利用h1和h2作差，正则表示前一个大，负则表示后一个大
        res=res.stream().sorted((h1,h2)->
                -(h1.getCount()-h2.getCount())
        ).limit(10).collect(Collectors.toList());
        return res;

    }
    // todo 按月度统计热度情况
    // todo 按月度统计热度情况、分终端的情况
    // todo 分终端进行查询
    // todo 筛选热度区间的数据
    // todo 查询某个标题的热度
    // todo  按周统计热度情况、分终端的情况
    // todo  按作者统计...............
}
